#ifndef __LB_SERVER_H__
#define __LB_SERVER_H__

#include <memory> // for auto_ptr
#include <string>

namespace dsth {
class PBCodec;
class PBDispatcher;
class Heartbeat;
class QueryStatus;
class NotifyStatus;
class EventLoop;
class ChannelBuffer;
class Timestamp;
class ServerBootstrap;
class ClientBootstrap;
class InetSocketAddress;
class Connection;
class Mutex;
class LBServer {
public:
    enum Status {
        kBooting = 0,
        kMaster,
        kSlaver
    };
    LBServer(EventLoop* loop, const InetSocketAddress& addr, const InetSocketAddress& buddy, int heartbeatInterval);
    ~LBServer();
    void Run();
    void OnConnect(Connection* conn);
    void OnDisConnect(Connection* conn);
    void OnErrorMsg(Connection* conn, ChannelBuffer* buffer, Timestamp time);
    void OnHeartbeat(const Connection* conn, const Heartbeat* req, Timestamp time);
    void OnQueryStatus(const Connection* conn, const QueryStatus* req, Timestamp time);
    void OnNotifyStatus(const Connection* conn, const NotifyStatus* req, Timestamp time);
    void OnConnectRefused();
    void OnConnectToBuddy(Connection* conn);
    void OnDisConnectFromBuddy(Connection* conn);

private:
    LBServer(const LBServer&);
    void operator=(const LBServer&);

    void CheckBuddyResponse();
    void HeartbeatPeriod();
    void CheckMasterHeartbeat();

    std::auto_ptr<ServerBootstrap> server_;
    std::auto_ptr<ClientBootstrap> client_;
    std::auto_ptr<PBDispatcher> dispatcher_;
    std::auto_ptr<PBCodec> codec_;
    Status status_;
    EventLoop* loop_;
    bool conn_buddy_;
    Mutex* mutex_; // guard master_hb_
    Timestamp master_hb_;
    int expired_;
};

} // namespace
#endif // __LB_SERVER_H__
